package cc.jinglupeng.wechat.api;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.apache.log4j.Logger;

import cc.jinglupeng.wechat.WechatCacheManager;
import cc.jinglupeng.wechat.bean.JSAPITicket;
import cc.jinglupeng.wechat.util.SignUtils;
import cc.jinglupeng.wechat.util.WxHttpUtils;

/**
 * JS-SDK API
 * 
 * @author jinglupeng.cc
 */
public class JSAPI {

	private static Logger logger = Logger.getLogger(JSAPI.class);

	private static String GET_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";

	/**
	 * 直接从微信公众平台获取JSAPITicket
	 * 
	 * @param appId
	 *            -第三方用户唯一凭证
	 * @return
	 */
	public static JSAPITicket getJSAPITicketFromServer(String appId) {
		String token = BaseAPI.getAccessToken(appId);
		if (token == null) {
			logger.error("获取JSAPI Ticket失败，获取AccessToken失败!");
			return new JSAPITicket(-4, "获取AccessToken失败");
		}
		String url = GET_TICKET_URL.replace("ACCESS_TOKEN", token);
		try {
			JSAPITicket ticket = WxHttpUtils.get(url, JSAPITicket.class);
			if (ticket.isSuccess()) {
				ticket.setCreateTime(System.currentTimeMillis());
				WechatCacheManager.cacheJSAPITicket(appId, ticket);
				return ticket;
			}
			logger.error("获取JSAPITicket失败，AppId:" + appId + ",错误码："
					+ ticket.getErrcode());
			return new JSAPITicket(-2, "获取JSAPITicket失败");
		} catch (Exception e) {
			logger.error("获取JSAPI Ticket失败, 错误信息：" + e.getMessage());
			return new JSAPITicket(-5, "未知错误！");
		}
	}

	/**
	 * 获取JSAPITicket，优先从缓存获取。获取JSAPITicket接口每天可获取次数有限，每次有效期7200秒，
	 * 所以需要对JSAPITicket进行缓存
	 * 
	 * @param appId
	 *            -第三方用户唯一凭证
	 * @return
	 */
	public static String getJSAPITicket(String appId) {
		JSAPITicket ticket = WechatCacheManager.getJSAPITicket(appId);
		if (ticket == null) {
			synchronized (JSAPI.class) {
				ticket = WechatCacheManager.getJSAPITicket(appId);
				if (ticket != null) {
					return ticket.getTicket();
				} else {
					ticket = getJSAPITicketFromServer(appId);
					if (!ticket.isSuccess()) {
						logger.error("从微信服务器获取JSAPITicket失败，AppId:" + appId);
						return null;
					}
					logger.debug("Ticket:" + ticket.getTicket());
					return ticket.getTicket();
				}
			}
		} else {
			return ticket.getTicket();
		}
	}

	public static Map<String, String> getJSAPIConfig(String appId, String url) {
		String jsapi_ticket = JSAPI.getJSAPITicket(appId);
		if (jsapi_ticket == null) {
			logger.error("JSAPI签名失败，获取JSAPITicket失败");
			return null;
		}
		String timeStamp = Long.toString(System.currentTimeMillis() / 1000);
		Map<String, String> params = new HashMap<String, String>();
		params.put("jsapi_ticket", jsapi_ticket);
		params.put("nonceStr", UUID.randomUUID().toString());
		params.put("timestamp", timeStamp);
		params.put("url", url);
		String signature = SignUtils.sha1Sign(params);
		params.put("signature", signature);
		params.put("appId", appId);
		params.remove("jsapi_ticket");
		params.remove("url");
		return params;
	}

}
